//
//  ZDUserAccount.m
//  OCSinaWeiBo
//
//  Created by Apple on 15/10/30.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import "ZDUserAccount.h"
#import "ZDNetworkTool.h"

#define access_token_key @"access_token"
#define expires_in_key @"expires_in"
#define uid_key @"uid"
#define name_key @"name"
#define avatar_large_key @"avatar_large"
#define access_date_key @"access_date"

#define ZDFilePath [(NSString *)NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"userAccount.plist"]

/**
 *  缓存用户账号信息
 */
static ZDUserAccount *userAccount = nil;

@interface ZDUserAccount () <NSCoding>

/**
 *  用于调用access_token，接口获取授权后的access token
 */
@property (nonatomic, copy) NSString *access_token;

/**
 *  access_token的生命周期，单位是秒数
 */
@property (nonatomic, copy) NSNumber *expires_in;

/**
 *  access_token的生命周期（该参数即将废弃，开发者请使用expires_in）
 */
//@property (nonatomic, copy) NSString *remind_in;

/**
 *  当前授权用户的UID
 */
@property (nonatomic, copy) NSString *uid;


/**
 *  自定义属性保存 access_token的生命周期 日期格式
 */
@property (nonatomic, strong) NSDate *access_date;


@end

@implementation ZDUserAccount


- (instancetype) initWithDictionary:(NSDictionary *)dict
{
    if (self = [super init])
    {
        [self setValuesForKeysWithDictionary:dict];
        
        //转换为日期
        _access_date = [NSDate dateWithTimeIntervalSinceNow:_expires_in.doubleValue];
    }
    
    return self;
}


//解决字典转模型中 模型因为缺少属性导致程序崩溃的问题
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    
}


+ (instancetype) userAccountWithDictionary:(NSDictionary *)dict
{
    return [[self alloc] initWithDictionary:dict];
}


/**
 *  保存账户数据
 */
- (void)saveUserAccount
{
    [NSKeyedArchiver archiveRootObject:self toFile:ZDFilePath];
}

/**
 *  加载账户数据  可能会有很多地方需要加载账户信息 如果每次取沙盒加载 影响性能 所以加入缓存机制优化
 */
+ (instancetype)loadUserAccount
{
    //1.内存没有 才从沙盒加载
    if (!userAccount)
    {
//        ZDLog(@"从沙盒加载");
        userAccount = [NSKeyedUnarchiver unarchiveObjectWithFile:ZDFilePath];
        
        ZDLog(@"%@", userAccount);
    }
    
    //2.从沙盒加载还是可能什么也加载不到 另外 如果能加载到 还需要判断accessToken是否过期
    //如果userAccount有值 并且 其accessToken没有过期
    if (userAccount && [userAccount.access_date compare:[NSDate date]] == NSOrderedDescending)
    {
        return userAccount;
    }

    return nil;
}

/**
 *  加载用户信息
 *
 *  @param successBlock 请求成功回调
 *  @param failureBlock 请求失败回调
 */
- (void)loadUserInfoWithSuccess:(void (^)(id responseObject))successBlock failure:(void (^)(NSError *error))failureBlock
{
    [[ZDNetworkTool sharedInstance] loadUserInfoWithAccess_token:_access_token uid:_uid success:^(id responseObject) {
        
        successBlock(responseObject);
        
    } failure:^(NSError *error) {
        
        failureBlock(error);
    }];
}


/**
 *  保存用户信息
 */
- (void)saveUserInfo
{
    //保存到沙盒
    [self saveUserAccount];
    
    //同步到内存缓存
    userAccount = self;
}

/**
 *  是否登录
 */
+ (BOOL)isLogin
{
    //如果从沙盒能够加载到账号 就说明登录过
    if ([self loadUserAccount])
    {
        return YES;
    }
    
    return NO;
}


#pragma mark - 实现协议方法
/**
 *  归档
 */
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_access_token forKey:access_token_key];
    [aCoder encodeObject:_expires_in forKey:expires_in_key];
    [aCoder encodeObject:_uid forKey:uid_key];
    [aCoder encodeObject:_name forKey:name_key];
    [aCoder encodeObject:_avatar_large forKey:avatar_large_key];
    [aCoder encodeObject:_access_date forKey:access_date_key];
    
}

/**
 *  解档
 */
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init])
    {
        _access_token = [aDecoder decodeObjectForKey:access_token_key];
        _expires_in = [aDecoder decodeObjectForKey:expires_in_key];
        _uid = [aDecoder decodeObjectForKey:uid_key];
        _name = [aDecoder decodeObjectForKey:name_key];
        _avatar_large = [aDecoder decodeObjectForKey:avatar_large_key];
        _access_date = [aDecoder decodeObjectForKey:access_date_key];
    }
    
    return self;
}


- (NSString *)description
{
//    return [NSString stringWithFormat:@"access_token: %@, expires_in: %@, uid: %@, access_date: %@, name: %@, avatar_large: %@", _access_token, _expires_in, _uid, _access_date, _name, _avatar_large];
    
    NSArray *array = @[@"access_token", @"expires_in", @"uid", @"access_date", @"name", @"avatar_large"];
    
    return [NSString stringWithFormat:@"\n\tUserAccount:%@", [self dictionaryWithValuesForKeys:array]];
}

@end
